<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
</head>

<body>
  <button id="handle">测试不做函数节流/防抖</button>
  <button id="throttle">测试函数节流</button>
  <button id="debounce">测试函数防抖</button>

  <script>
    /* 处理点击事件的回调函数 */
    function handleClick (event) { // 处理事件的回调
      console.log('处理点击事件')
    }
    document.getElementById('handle').onclick = handleClick
    // document.getElementById('throttle').onclick = _.throttle(handleClick,1000)
    // document.getElementById('debounce').onclick = _.debounce(handleClick,1000)

    /*
    throttle和debounce是高阶函数  参数是函数 返回值也是函数
    */
  </script>


  <script>

    /*
    用于产生节流函数的工具函数
    如果当前事件发生的时间与上一次处理的时间差大于指定的时间, 才调用回调处理
    */

    function throttle (callback, time) {
      // 用于保存处理事件的时间, 初始值为0, 保证第一次会执行
      let start = 0
      // 返回事件监听函数 ==> 每次事件发生都会执行
      return function (event) {
        console.log('---throttle') // 点击一次执行一次
        // 发生事件的当前时间
        const now = Date.now()
        // 与上一次处理事件的时差大于time的时间
        if (now - start > time) {
          // 执行处理事件的函数
          // console.log(event.target === this);  // true
          callback.call(event.target, event)
          // 保证当前时间 记录最新的处理时间
          start = now
        }
      }
    }
    // 测试节流
    document.getElementById('throttle').onclick = throttle(handleClick,1000)

    /* 
    防抖工具函数
    和节流函数不同:  用定时器来做 会将之前触发 但未执行的调用回调的延迟任务取消
    */

    function debounce (callback,time){
      // 用来保存待执行的延迟任务 (定时器)
      let timeoutId
      return function (e){
        console.log('debounce.....')
        // 将前面已经触发的  但是未执行的调用回调 延迟任务取消
        if(timeoutId){
          clearTimeout(timeoutId)
        }
        // 启动一个新定时器 准备执行回调处理  要保存定时器的id
        timeoutId = setTimeout(()=>{
          // 调用回调处理
          callback.call(this,e)
          // 重置定时器id
          timeoutId = null
        },time)
      }
    }
    // 测试防抖
    document.getElementById('debounce').onclick = debounce(handleClick,1000)
  </script>


  <!-- 
    1. 事件频繁触发可能造成的问题?
        1). 一些浏览器事件:window.onresize、window.mousemove等，触发的频率非常高，会造成浏览器性能问题
        2). 如果向后台发送请求，频繁触发，对服务器造成不必要的压力
    
    2. 如何限制事件处理函数频繁调用
        1). 函数节流
        2). 函数防抖

    3. 函数节流(throttle)
        1). 理解: 
            在函数需要频繁触发时: 函数执行一次后，只有大于设定的执行时间后才会执行第二次
            适合多次事件按时间做平均分配触发 (触发少量几次)
        2). 场景：
            窗口调整（resize）
            页面滚动（scroll）
            DOM 元素的拖拽功能实现（mousemove）
            抢购疯狂点击（click）
        3) 自定义: 
          判断间隔时间, 只有大于指定的时间, 才去执行真正处理事件的回调函数
    4. 函数防抖(debounce)
        1). 理解:
            在函数需要频繁触发时: 在规定时间内，只让最后一次生效，前面的不生效。
            适合多次事件一次响应的情况
        2). 场景：
            输入框实时搜索联想（keyup/input）
        3) 自定义: 
          先清除前面未完成的定时器
          启动一个定时器, 延迟指定的时间, 准备去调用真正处理事件的回调函数
  -->


</body>

</html>